package com.bf.electroplating.service.compoent;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * HJ212测试客户端
 * 用于测试HJ212服务器的功能
 */
@Slf4j
@Component
public class HJ212TestClient {
    
    private SocketChannel socketChannel;
    private ExecutorService listenerExecutor;
    private AtomicBoolean isConnected = new AtomicBoolean(false);
    private AtomicBoolean shouldStop = new AtomicBoolean(false);
    
    public static void main(String[] args) {
        HJ212TestClient client = new HJ212TestClient();
        client.connectToServer("36.134.118.75", 8103);
    }
    /**
     * 连接到HJ212服务器并保持连接
     * 
     * @param host 服务器地址
     * @param port 服务器端口
     * @return 是否连接成功
     */
    public boolean connectToServer(String host, int port) {
        try {
            // 如果已经连接，先断开
            if (isConnected.get()) {
                disconnectFromServer();
            }
            
            // 创建新连接
            socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(true);
            socketChannel.connect(new InetSocketAddress(host, port));
            
            isConnected.set(true);
            shouldStop.set(false);
            
            // 启动监听线程
            listenerExecutor = Executors.newSingleThreadExecutor();
            listenerExecutor.submit(this::listenForServerCommands);
            
            log.info("已连接到HJ212服务器: {}:{}", host, port);
            return true;
            
        } catch (IOException e) {
            log.error("连接HJ212服务器失败: {}:{}", host, port, e);
            isConnected.set(false);
            return false;
        }
    }
    
    /**
     * 断开与服务器的连接
     */
    public void disconnectFromServer() {
        shouldStop.set(true);
        isConnected.set(false);
        
        if (listenerExecutor != null) {
            listenerExecutor.shutdown();
            listenerExecutor = null;
        }
        
        if (socketChannel != null) {
            try {
                socketChannel.close();
                socketChannel = null;
            } catch (IOException e) {
                log.error("关闭连接失败", e);
            }
        }
        
        log.info("已断开与HJ212服务器的连接");
    }
    
    /**
     * 监听服务器指令的线程方法
     */
    private void listenForServerCommands() {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        
        while (!shouldStop.get() && isConnected.get()) {
            try {
                // 清空缓冲区
                buffer.clear();
                
                // 读取服务器数据
                int bytesRead = socketChannel.read(buffer);
                
                if (bytesRead > 0) {
                    buffer.flip();
                    byte[] data = new byte[bytesRead];
                    buffer.get(data);
                    String command = new String(data, StandardCharsets.UTF_8);
                    
                    log.info("收到服务器指令: {}", command);
                    
                    // 处理服务器指令
                    handleServerCommand(command);
                    
                } else if (bytesRead == -1) {
                    // 服务器关闭连接
                    log.info("服务器关闭了连接");
                    break;
                }
                
                // 短暂休眠避免CPU占用过高
                Thread.sleep(100);
                
            } catch (IOException e) {
                if (!shouldStop.get()) {
                    log.error("读取服务器数据失败", e);
                }
                break;
            } catch (InterruptedException e) {
                log.info("监听线程被中断");
                break;
            }
        }
        
        // 连接断开，更新状态
        isConnected.set(false);
        log.info("监听线程结束");
    }
    
    /**
     * 处理服务器指令
     * 
     * @param command 服务器指令
     */
    private void handleServerCommand(String command) {
        try {
            // 这里可以根据具体的指令格式进行处理
            // 例如：解析指令类型，执行相应操作等
            
            if (command.contains("STOP_PRODUCTION")) {
                log.info("收到停止生产指令，执行停止操作...");
                // 执行停止生产的具体逻辑
                sendResponseToServer("STOP_PRODUCTION_ACK");
                
            } else if (command.contains("START_PRODUCTION")) {
                log.info("收到开始生产指令，执行开始操作...");
                // 执行开始生产的具体逻辑
                sendResponseToServer("START_PRODUCTION_ACK");
                
            } else if (command.contains("GET_STATUS")) {
                log.info("收到状态查询指令，返回当前状态...");
                // 返回当前状态信息
                sendResponseToServer("STATUS: RUNNING, TEMPERATURE: 25.5, PH: 7.2");
                
            } else if (command.contains("GET_STATUS_REPORT")) {
                log.info("收到状态报告指令，返回详细报告...");
                // 返回详细状态报告
                sendResponseToServer("STATUS_REPORT: PRODUCTION_RATE=85%, QUALITY_SCORE=92, MAINTENANCE_DUE=2024-02-01");
                
            } else {
                log.info("收到未知指令: {}", command);
//                sendResponseToServer("UNKNOWN_COMMAND");
            }
            
        } catch (Exception e) {
            log.error("处理服务器指令失败", e);
            sendResponseToServer("ERROR: " + e.getMessage());
        }
    }
    
    /**
     * 向服务器发送响应
     * 
     * @param response 响应内容
     */
    private void sendResponseToServer(String response) {
        if (!isConnected.get() || socketChannel == null) {
            log.warn("未连接到服务器，无法发送响应");
            return;
        }
        
        try {
            byte[] data = response.getBytes(StandardCharsets.UTF_8);
            ByteBuffer buffer = ByteBuffer.wrap(data);
            socketChannel.write(buffer);
            log.info("已向服务器发送响应: {}", response);
        } catch (IOException e) {
            log.error("发送响应到服务器失败", e);
            isConnected.set(false);
        }
    }
    
    /**
     * 发送测试数据包到HJ212服务器（保持连接版本）
     * 
     * @param testData 测试数据
     * @return 是否发送成功
     */
    public boolean sendTestPacket(String testData) {
        if (!isConnected.get() || socketChannel == null) {
            log.warn("未连接到服务器，请先调用connectToServer方法");
            return false;
        }
        testData+="\r\n";
        try {
            byte[] data = testData.getBytes(StandardCharsets.UTF_8);
            ByteBuffer buffer = ByteBuffer.wrap(data);
            socketChannel.write(buffer);
            
            log.info("已发送测试数据: {}", testData);
            return true;
            
        } catch (IOException e) {
            log.error("发送测试数据失败", e);
            isConnected.set(false);
            return false;
        }
    }
    
    /**
     * 发送测试数据包到HJ212服务器（一次性连接版本，保持向后兼容）
     * 
     * @param host 服务器地址
     * @param port 服务器端口
     * @param testData 测试数据
     * @return 服务器响应
     */
    public String sendTestPacket(String host, int port, String testData) {
        SocketChannel tempChannel = null;
        try {
            // 连接服务器
            tempChannel = SocketChannel.open();
            tempChannel.configureBlocking(true);
            tempChannel.connect(new InetSocketAddress(host, port));
            
            log.info("已连接到HJ212服务器: {}:{}", host, port);
            
            // 发送测试数据
            byte[] data = testData.getBytes(StandardCharsets.UTF_8);
            ByteBuffer buffer = ByteBuffer.wrap(data);
            tempChannel.write(buffer);
            
            log.info("已发送测试数据: {}", testData);
            
            // 接收响应
            ByteBuffer responseBuffer = ByteBuffer.allocate(1024);
            int bytesRead = tempChannel.read(responseBuffer);
            
            if (bytesRead > 0) {
                responseBuffer.flip();
                byte[] responseData = new byte[bytesRead];
                responseBuffer.get(responseData);
                String response = new String(responseData, StandardCharsets.UTF_8);
                log.info("收到服务器响应: {}", response);
                return response;
            } else {
                log.warn("未收到服务器响应");
                return null;
            }
            
        } catch (IOException e) {
            log.error("发送测试数据失败", e);
            return null;
        } finally {
            if (tempChannel != null) {
                try {
                    tempChannel.close();
                } catch (IOException e) {
                    log.error("关闭连接失败", e);
                }
            }
        }
    }
    
    /**
     * 发送标准HJ212数据包
     * 
     * @param host 服务器地址
     * @param port 服务器端口
     * @return 服务器响应
     */
    public String sendStandardPacket(String host, int port) {
        // 标准HJ212数据包格式
        String standardPacket = "##0000ST=91;CN=9011;PW=123456;MN=00000000000000000000;Flag=5;CP=&&RtdInterval=30&&\r\n";
        return sendTestPacket(host, port, standardPacket);
    }
    
    /**
     * 发送实时数据包
     * 
     * @param host 服务器地址
     * @param port 服务器端口
     * @param pollutantCode 污染物代码
     * @param value 数值
     * @return 服务器响应
     */
    public String sendRealTimeData(String host, int port, String pollutantCode, String value) {
        // 实时数据包格式
        String realTimePacket = String.format("##0000ST=91;CN=2011;PW=123456;MN=00000000000000000000;Flag=5;CP=&&DataTime=20231201120000;%s-Rtd=%s,%s-Flag=N;%s-Rtd=%s,%s-Flag=N&&\r\n", 
            pollutantCode, value, pollutantCode, pollutantCode, value, pollutantCode);
        return sendTestPacket(host, port, realTimePacket);
    }
    
    /**
     * 检查是否已连接到服务器
     * 
     * @return 是否已连接
     */
    public boolean isConnected() {
        return isConnected.get();
    }
    
    /**
     * 发送实时数据包（保持连接版本）
     * 
     * @param pollutantCode 污染物代码
     * @param value 数值
     * @return 是否发送成功
     */
    public boolean sendRealTimeData(String pollutantCode, String value) {
        if (!isConnected.get()) {
            log.warn("未连接到服务器，请先调用connectToServer方法");
            return false;
        }
        
        // 实时数据包格式
        String realTimePacket = String.format("##0000ST=91;CN=2011;PW=123456;MN=00000000000000000000;Flag=5;CP=&&DataTime=20231201120000;%s-Rtd=%s,%s-Flag=N;%s-Rtd=%s,%s-Flag=N&&\r\n", 
            pollutantCode, value, pollutantCode, pollutantCode, value, pollutantCode);
        
        return sendTestPacket(realTimePacket);
    }
    
    /**
     * 发送标准HJ212数据包（保持连接版本）
     * 
     * @return 是否发送成功
     */
    public boolean sendStandardPacket() {
        if (!isConnected.get()) {
            log.warn("未连接到服务器，请先调用connectToServer方法");
            return false;
        }
        
        // 标准HJ212数据包格式
        String standardPacket = "##0000ST=91;CN=9011;PW=123456;MN=00000000000000000000;Flag=5;CP=&&RtdInterval=30&&\r\n";
        return sendTestPacket(standardPacket);
    }
} 

